package com.wdb007.venus.svc.biz.wxapp;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wdb007.venus.svc.biz.manager.ConfigInfoManager;
import com.wdb007.venus.svc.biz.manager.SmsSendManager;
import com.wdb007.venus.svc.biz.utils.CommonUtil;
import com.wdb007.venus.svc.biz.utils.DateFormatUtil;
import com.wdb007.venus.svc.dal.book.dao.BookInfoDAO;
import com.wdb007.venus.svc.dal.user.dao.UserInfoDAO;
import com.wdb007.venus.svc.dal.user.dao.WxUserFormidDAO;
import com.wdb007.venus.svc.dal.user.dao.WxUserRelationDAO;
import com.wdb007.venus.svc.dal.user.model.WxUserFormidDO;
import com.wdb007.venus.svc.dal.user.model.WxUserRelationDO;
import com.wdb007.venus.svc.dal.vip.dao.VipMemberDAO;
import com.wdb007.venus.svc.dal.vip.model.VipMemberDO;
import com.wdb007.venus.svc.facade.WxAPPMessagePushService;
import com.wdb007.venus.svc.facade.constant.BizConstants;
import com.wdb007.venus.svc.facade.wxapp.model.SendMsgReqDTO;


@Service("wxAPPMessagePushService")
public class WxAPPMessagePushServiceImpl implements WxAPPMessagePushService {
	private final static Logger logger = LoggerFactory.getLogger(WxAPPMessagePushServiceImpl.class);
	@Autowired
	private WxUserFormidDAO wxUserFormidDAO;

	@Autowired
	private WxUserRelationDAO wxUserRelationDAO;
	
	@Autowired
	private SmsSendManager smsSendManager;
	
	@Autowired
	private UserInfoDAO userInfoDAO;
	
	@Autowired
	private BookInfoDAO bookInfoDAO;
	
	@Autowired
	private VipMemberDAO vipMemberDAO;
	
	@Autowired
	private ConfigInfoManager configInfoManager;
	
	@Override
	public String getAccessToken(String grant_type, String appid, String secret) {
		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
		// TODO if token存在,且过期时间在范围内，直接返回wx token appidtoken
		url = url.replace("APPID", appid).replace("APPSECRET", secret);
		JSONObject jsonObject = CommonUtil.httpsRequest(url, "GET", null);

		String accessToken = jsonObject.getString("access_token");
		return accessToken;
	}

	@Override
	public String sendTemplateMsg(SendMsgReqDTO dto) {
		// TODO Auto-generated method stub
		logger.info("SendMsgReq：" + JSON.toJSONString(dto));
		String appid = configInfoManager.getValue("wxapp.appid");
		String secret = configInfoManager.getValue("wxapp.secret");
		String accessToken = getAccessToken(null, appid, secret);

		String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + accessToken;
		dto.setAccess_token(accessToken);
		String outputStr = JSON.toJSONString(dto);
		JSONObject jsonObject = CommonUtil.httpsRequest(url, "POST", outputStr);
		logger.info("SendMsgReq jsonObject：" + jsonObject);
		// 发送成功update
		updateMsgFormId(appid, dto.getTouser(), null, dto.getForm_id(), dto.getData().toString());
		return jsonObject.toString();
	}

	@Override
	public void saveMsgFormId(String appid, String openid, Long userid, String formId) {
		WxUserFormidDO wxUserFormidDO = new WxUserFormidDO();
		wxUserFormidDO.setAppid(appid);
		wxUserFormidDO.setCreateTime(new Date());
		wxUserFormidDO.setFormId(formId);
		wxUserFormidDO.setOpenid(openid);
		wxUserFormidDO.setUserid(userid);
		// TODO UUID
		UUID uuid = UUID.randomUUID();
		String str = uuid.toString();
		String uuidStr = str.replace("-", "");
		wxUserFormidDO.setId(uuidStr);

		wxUserFormidDAO.insertSelective(wxUserFormidDO);
	}

	@Override
	public void updateMsgFormId(String appid, String openid, Long userid, String formId, String content) {
		WxUserFormidDO wxUserFormidDO = new WxUserFormidDO();
		wxUserFormidDO.setAppid(appid);
		wxUserFormidDO.setOpenid(openid);
		wxUserFormidDO.setUserid(userid);
		wxUserFormidDO.setFormId(formId);

		wxUserFormidDO.setUseTime(new Date());
		wxUserFormidDO.setStatus((short) 1);
		wxUserFormidDO.setContent(content);

		wxUserFormidDAO.updateUseTime(wxUserFormidDO);
	}

	@Override
	public String selectByWxOpenid(String appid, String openid, Long userid) {
		WxUserFormidDO wxUserFormidDO = new WxUserFormidDO();
		wxUserFormidDO.setAppid(appid);
		wxUserFormidDO.setOpenid(openid);
		wxUserFormidDO.setUserid(userid);

		wxUserFormidDO.setCreateTime(DateFormatUtil.getSomeDay(new Date(), -7));//微信要求，7天内的时间
		String formId = wxUserFormidDAO.selectByWxOpenid(wxUserFormidDO);

		return formId;
	}

	/**
	 * 微信小程序推送内容
	 * 
	 * @param templateId
	 *            模板ID
	 * @param content
	 * @param userid
	 * @param openid
	 * @param page
	 *            跳转小程序页面
	 */
	public void sendContent(String templateId, Map<String, Object> content, Long userid, String openid, String page) {
		// 根据userid，appid查找openid
		logger.info("sendContent,templateId:{},userid:{},openid:{},content:{},page:{}", templateId, userid, openid, content, page);
		if(!ObjectUtils.isEmpty(templateId)) {
			String appid = configInfoManager.getValue("wxapp.appid");
			if (openid == null && userid != null) {
				// 查询出
				WxUserRelationDO wxUserRelationDO = new WxUserRelationDO();
				wxUserRelationDO.setAppId(appid);
				wxUserRelationDO.setUserId(userid);
				List<WxUserRelationDO> list = wxUserRelationDAO.listByCondition(wxUserRelationDO);//根据appid和userid查询绑定的微信
				if (list != null && list.size() > 0) {
					for (WxUserRelationDO wurd : list) {//向每个微信用户发消息
						// appid,userid,openid查询
						if(!"null".equals(wurd.getUnionid())) {//发消息防止发"null"的userid
							String formId = selectByWxOpenid(appid, wurd.getOpenid(), userid);
							logger.info("sendWxMessage appid:{},openid:{},userid:{},formId:{}",appid, wurd.getOpenid(), userid, formId);
							if (formId != null && formId.length() > 0) {
								openid = wurd.getOpenid();
								// 发送信息content
								SendMsgReqDTO dto = new SendMsgReqDTO();
								dto.setData(content);
								dto.setForm_id(formId);
								dto.setTemplate_id(templateId);
								dto.setTouser(openid);
								if (!ObjectUtils.isEmpty(page)) {
									dto.setPage(page);
								}
								sendTemplateMsg(dto);
							}
						}

					}

				}
			}
		}
		
	}

	// 充值到账
	public void sendRechangeToAccountNotice(String mobileNo, int payType, Date payTime, BigDecimal addAmount,
			Long userid) {
		String value1 = mobileNo;// 充值账户
		String value2 = "￥" + addAmount ;// 充值金额
		
		String value3 = "系统赠送";//充值方式
		int type = 0;
		if(BizConstants.ACCOUNT_CASH_CHARGE_TYPE_20.equals(payType) || BizConstants.ACCOUNT_CASH_CHARGE_TYPE_10.equals(payType)) {
			value3 = "在线支付";
			type = 1;
		}
		String value4 = DateFormatUtil.formatDate3(payTime);//充值时间
		String value5 = "已成功充值";// 备注

		Map<String, Object> content = convertContent(value1, value2, value3, value4, value5);

		sendContent(BizConstants.RECHARGE_TO_ACCOUNT_NOTICE, content, userid, null,
				BizConstants.RECHARGE_TO_ACCOUNT_PAGE);
		
		//短信发送
		smsSendManager.sendRechangeToAccountMsg(mobileNo, addAmount.toString(), type);
	}	
	// 会员卡到账通知
	public void sendVipCardToAccountNotice(int vipType, BigDecimal addAmount, String payTime,
			Long userid, String endtime, int chargeType) {
		try {
			String value1 = "月卡";// 会员卡类型 1 月卡，2 年卡
			if(BizConstants.VIP_TYPE_2.equals(vipType)) {
				value1 = "年卡";
			}
			String value2 = (addAmount != null ? ("￥" + addAmount.setScale(2)) : ("￥0"));// 充值金额
			String value3 = "在线支付";// 购买方式、在线支付/系统赠送
			if(BizConstants.VIP_CHARGE_TYPE_20.equals(chargeType)) {
				value3 = "系统赠送";
			}else if(BizConstants.VIP_CHARGE_TYPE_30.equals(chargeType)) {
				value3 = "地推赠送";
			}
			
			String value4 = payTime;// DateFormatUtil.formatDate3(new Date());//购买时间
			String value5 = "恭喜您成为" + value1 + "会员";// 备注

			Map<String, Object> content = convertContent(value1, value2, value3, value4, value5);

			sendContent(BizConstants.VIP_CARD_TO_ACCOUNT_NOTICE, content, userid, null,
					BizConstants.VIP_CARD_TO_ACCOUNT_PAGE);
			//短信发送
			String mobileNo = userInfoDAO.get(userid).getMobileNo();
			smsSendManager.sendPaidVipToAccountMsg(mobileNo, value1, endtime, chargeType);
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	// 超额借阅通知
	public void sendBorrowBookOverNotice(int borrowNum, int outNum, String outBookName, Date borrowTime,
			Long userid) {
		String value1 = borrowNum + "本";// 借阅数量
		String value2 = outNum + "本";// 超额数量
		String value3 = outBookName;// 超额书籍名称
		String value4 = DateFormatUtil.formatDate3(borrowTime);// 借阅时间
		String value5 = "超额借阅的书籍，按照每天2元/本计费";// 备注
		try {
			Map<String, Object> content = convertContent(value1, value2, value3, value4, value5);

			sendContent(BizConstants.BORROW_BOOK_OVER_NOTICE, content, userid, null, BizConstants.BORROW_BOOK_OVER_PAGE);
			
			String mobileNo = userInfoDAO.get(userid).getMobileNo();
			smsSendManager.sendBoorowBookOverMsg(mobileNo, borrowNum+"", outNum+"");
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	// 押金缴纳成功通知
	public void sendPayDepositNotice(BigDecimal money, String payType, String payTime, Long userid) {
		String value1 = "￥" + money;// 押金金额
		String value2 = payType;// 支付方式
		String value3 = payTime;// 超额书籍名称
		String value4 = "资腾(上海)网络科技有限公司";// 商户全称
		String value5 = "已成功缴纳押金";// 备注
		try {
			Map<String, Object> content = convertContent(value1, value2, value3, value4, value5);
			sendContent(BizConstants.PAY_DEPOSIT_NOTICE, content, userid, null, BizConstants.PAY_DEPOSIT_PAGE);
			//发送短信
			String mobileNo = userInfoDAO.get(userid).getMobileNo();
			smsSendManager.sendPayDepositMsg(mobileNo);
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 借阅费用已达上限通知
	 * @param bookName 
	 * @param bookPrice 原价
	 * @param borrowPrice 借阅费用
	 * @param userid
	 */
	public void sendBorrowFeeOverPriceNotice(String isbn, String bookPrice, String borrowPrice, Long userid) {
		
		String value2 = bookPrice;// 书籍价格
		String value3 = borrowPrice;// 借阅费用
		String value4 = "系统扣费";// 商户全称
		String value5 = "当前所借图书费用已经超过原书价格的70%，不再增加您的借阅费，您可以保留或者归还图书。";// 备注
		try {
			String value1 = bookInfoDAO.get(isbn).getBookName();// 借阅书籍
			Map<String, Object> content = convertContent(value1, value2, value3, value4, value5);

			sendContent(BizConstants.BORROW_FEE_OVER_PRICE_NOTICE, content, userid, null, BizConstants.BORROW_FEE_OVER_PRICE_PAGE);
			
			//短信发送
			String mobileNo = userInfoDAO.get(userid).getMobileNo();
			smsSendManager.sendBoorowFeeOverPriceMsg(mobileNo, value1, borrowPrice);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	//会员卡6天到期通知，到期的所有人
	public void sendVipExpireTimeNotice(){
		try {
			List<VipMemberDO> vipMemberDOs = vipMemberDAO.getAllVipMembers(new Date());
			for(VipMemberDO vipMemberDO:vipMemberDOs) {
				 
				int expireTime = (int) ((vipMemberDO.getEndTime().getTime() - new Date().getTime()) / (1000*3600*24));//间隔时间
				if(expireTime == 6) {
					String mobileNo = userInfoDAO.get(vipMemberDO.getUserId()).getMobileNo();
					smsSendManager.sendVipExpireTimeMsg(mobileNo, vipMemberDO.getValidFlag());
				}
				
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	/**
	 * userid -- 获得openid
	 * rewardsName -- 奖励名称 系统赠送的金额
	 * status -- 系统赠送 
	 * 
	 */
	public void sendMerchantActivityNotice(Long userid, String rewardsName, String status) {
		logger.info("sendMerchantActivityNotice begin");
		String value1 = "新人礼";
		String value2 = rewardsName;
		String value3 = "资腾（上海）网络科技有限公司";
		String value4 = "系统赠送";
		String value5 = "请点击至个人中心查看";
		Map<String, Object> content = convertContent(value1, value2, value3, value4, value5);

		sendContent(BizConstants.MERCHANT_ACTIVITY_NOTICE, content, userid, null, BizConstants.MERCHANT_ACTIVITY_PAGE);
	}
	
	/**
	 * 押金退款成功通知
	 */
	public void sendBackDepositSuccessNotice(Long userid) {
		//短信发送
		String mobileNo = userInfoDAO.get(userid).getMobileNo();
		smsSendManager.sendBackDepositSuccessMsg(mobileNo);
	}

	
	private Map<String, Object> convertContent(String value1, String value2, String value3, String value4,
			String value5) {
		Map<String, Object> content = new HashMap<>();

		Map<String, Object> keyword1 = new HashMap<>();
		keyword1.put("value", value1);//
		Map<String, Object> keyword2 = new HashMap<>();
		keyword2.put("value", value2);
		Map<String, Object> keyword3 = new HashMap<>();
		keyword3.put("value", value3);
		Map<String, Object> keyword4 = new HashMap<>();
		keyword4.put("value", value4);
		Map<String, Object> keyword5 = new HashMap<>();// 备注
		keyword5.put("value", value5);

		content.put("keyword1", keyword1);
		content.put("keyword2", keyword2);
		content.put("keyword3", keyword3);
		content.put("keyword4", keyword4);
		content.put("keyword5", keyword5);
		return content;
	}

	public void sendErrorMsg(String phone) {
		smsSendManager.sendErrorMsg(phone);
	}
}
